#include "pch.h"
#include "include/cvsreader.h"
#include "include/util.h"
#include "include/baseconfig.h"
#include "include/tinyxml2.h"
#include <iostream>
#include <sstream>

//-------------------------------------------------------------------------------------
CVSReader::~CVSReader()
{

}

bool CVSReader::LoadFile(const std::string& filename)
{
	m_ColNum = 0;
	m_ColMap.clear();
	std::string data = Config::GetConfig()->ReadFileContent(filename.c_str()).c_str();
	
	std::vector<std::string> Lines = Split(data, "\r\n");
	if (Lines.size() < 2)
	{
		return false;
	}
	std::string headStr = Lines[0];//Trim(Lines[0]);
	std::vector<std::string> colums = Split(headStr, "\t");
	int columsize = colums.size();
	char** p = (char**)malloc(columsize * sizeof(char*));
	if (!p)
	{
		return false;
	}
	int i = 0;
	for (std::vector<std::string>::iterator it = colums.begin(); it!= colums.end(); it++)
	{
		p[i++] = const_cast<char*>(it->c_str());
	}
	OnHeaderLine(p, columsize);
	free(p);
	//////////////////////////////////////////////////////////////
	headStr = Lines[1] ;//Trim(Lines[1]);
	colums = Split(headStr, "\t");
	columsize = colums.size();
	p = (char**)malloc(columsize * sizeof(char*));
	if (!p)
	{
		return false;
	}
	i = 0;
	for (std::vector<std::string>::iterator it = colums.begin(); it != colums.end(); it++)
	{
		p[i++] = const_cast<char*>(it->c_str());
	}
	OnCommentLine(p, columsize);
	free(p);

	//////////////////////////////////////////////////////////////
	int limitSize = m_ColMap.size();
	for (int n = 2; n< Lines.size(); n++)
	{
		headStr = Lines[n];//Trim(Lines[n]);
		if (headStr.empty())
		{
			continue;
		}
		colums = Split(headStr, "\t");
		columsize = colums.size();
		if (limitSize == 0 || limitSize > columsize)
		{
			return false;
		}
		p = (char**)malloc(columsize * sizeof(char*));
		if (!p)
		{
			return false;
		}
		i = 0;
		for (std::vector<std::string>::iterator it = colums.begin(); it != colums.end(); it++)
		{
			p[i++] = const_cast<char*>(it->c_str());
		}
// 		for (std::vector<int>::iterator it = m_ColMap.begin(); it != m_ColMap.end(); it++)
// 		{
// 			int index = *it;
// 			p[i++] = const_cast<char*>(colums[index].c_str());
// 		}
		if (!OnLine(p, columsize))
		{
			free(p);
			return false;
		}
		free(p);
	}
	
	return true;
}

bool CVSReader::LoadBuffer(std::string& buffer, const char* filename/* = ""*/)
{
	return true;
}

// int m_ColNum;
// std::vector<int> m_ColMap;
bool CVSReader::MapColHeader(const char** ColHeader, int HeaderCount, char** Fields, int FieldCount)
{
	if (HeaderCount > FieldCount)
	{
		return false;
	}
	
	for (int i = 0; i < HeaderCount; i++)
	{
		std::string col = ColHeader[i];
		bool bfind = false;
		int index = 0;
		for (int j = 0; j < FieldCount; j++)
		{
			std::string field = Fields[j];
			if (col == field)
			{
				bfind = true;
				index = j;
				break;
			}
		}
		if (!bfind)
		{
			return false;
		}
		m_ColMap.push_back(index);
	}
	//m_ColNum = HeaderCount;
	return true;
}


bool CVSReader::Parse(const char* Field, bool& b)
{
	std::string field = Field;
	if (field == "true" || field == "True" || field == "TRUE")
	{
		b = true;
	}
	else
	{
		b = false;
	}
	return true;
}

bool CVSReader::Parse(const char* Field, int& output)
{	
	std::string s(Field);
	if (s.empty())
	{
		output = 0;
		return true;
	}
	return tinyxml2::XMLUtil::ToInt(Field, &output);
}

bool CVSReader::Parse(const char* Field, uint& output)
{
	std::string s(Field);
	if (s.empty())
	{
		output = 0;
		return true;
	}
	return tinyxml2::XMLUtil::ToUnsigned(Field, &output);
}

bool CVSReader::Parse(const char* Field, float& output)
{
	std::string s(Field);
	if (s.empty())
	{
		output = 0.f;
		return true;
	}
	return tinyxml2::XMLUtil::ToFloat(Field, &output);
}

bool CVSReader::Parse(const char* Field, double& output)
{
	std::string s(Field);
	if (s.empty())
	{
		output = 0.0;
		return true;
	}
	return tinyxml2::XMLUtil::ToDouble(Field, &output);
}

bool CVSReader::Parse(const char* Field, long long& output)
{
	std::istringstream ss(Field);
	//ss << Field;
	ss >> output;
	return true;/*XMLUtil::ToUnsigned(Field, strlen(Field), &output);*/
}

bool CVSReader::Parse(const char* Field, std::string& output)
{
	output = Field;
	return true;
}


